//
//  SW_OCRCaptureViewController.m
//  cloud-ios-sdk-ocr-1.0.0
//
//  Created by Snail on 2020/8/20.
//  Copyright © 2020 huawei. All rights reserved.
//

#import "SW_OCRCaptureViewController.h"
#import <Photos/Photos.h>
#import "SW_CaptureView.h"
#import "UIImage+Clip.h"

@interface SW_OCRCaptureViewController ()<AVCaptureMetadataOutputObjectsDelegate,CAAnimationDelegate>

//捕获设备，通常是前置摄像头，后置摄像头，麦克风（音频输入）
@property(nonatomic)AVCaptureDevice *device;
//AVCaptureDeviceInput 代表输入设备，他使用AVCaptureDevice 来初始化
@property(nonatomic)AVCaptureDeviceInput *input;
//输出
@property (nonatomic)AVCaptureStillImageOutput *imageOutPut;
//session：由他把输入输出结合在一起，并开始启动捕获设备（摄像头）
@property(nonatomic)AVCaptureSession *session;
//图像预览层，实时显示捕获的图像
@property(nonatomic)AVCaptureVideoPreviewLayer *previewLayer;
//拍照
@property (nonatomic, strong) UIButton *photoBtn;
//取消
@property (nonatomic, strong) UIButton *cancleBtn;
////切换摄像头
//@property (nonatomic, strong) UIButton *changeBtn;
//确定选择当前照片
@property (nonatomic, strong) UIButton *confirmBtn;
//重新拍照
@property (nonatomic, strong) UIButton *reCamBtn;
//照片加载视图
@property (nonatomic, strong) UIImageView *imageView;
//对焦区域
@property (nonatomic, strong) UIImageView *focusView;
//下方功能区
@property (nonatomic, strong) UIView *bottomView;
//拍到的照片
@property (nonatomic, strong) UIImage *image;
//照片的信息
@property (nonatomic, strong) NSDictionary *imageDict;
//是否可以拍照
@property (nonatomic, assign) BOOL canCa;
//闪光灯模式
@property (nonatomic, assign) AVCaptureFlashMode flahMode;
//前后摄像头
@property (nonatomic, assign) AVCaptureDevicePosition cameraPosition;

@property (nonatomic, strong) SW_CaptureView *captureView;//边框

@property (nonatomic, strong) UILabel *tipLabel;//提示字

@property (nonatomic, assign) CGRect captureRect;


@end

@implementation SW_OCRCaptureViewController
#pragma mark - 当前视图控制器的初始化
- (instancetype)init
{
    self = [super init];
    if (self) {
        _canCa = [self canUserCamear];
        self.modalPresentationStyle =UIModalPresentationFullScreen;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor =[UIColor blackColor];
    if (_canCa) {
        [self customCamera];
        [self customUI];
        [self reSetCaptureRect];
    }
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
}

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    [self reSetCaptureRect];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (_canCa ==NO) {
        UIAlertController *alertVC =[UIAlertController alertControllerWithTitle:@"请打开相机权限" message:@"设置->隐私->相机" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *closeAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
        [alertVC addAction:closeAction];
        UIAlertAction *setingAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
        [alertVC addAction:setingAction];
        [self presentViewController:alertVC animated:YES completion:nil];
    }
}

#pragma mark - 自定义视图
- (void)customUI {

    [self.view addSubview:self.focusView];
    [self.view addSubview:self.captureView];
    [self.view addSubview:self.cancleBtn];
    [self.view addSubview:self.tipLabel];
    [self.view addSubview:self.bottomView];
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusGesture:)];
    [self.view addGestureRecognizer:tapGesture];
    
}
#pragma mark - 自定义相机
- (void)customCamera{
    //生成会话，用来结合输入输出
    self.session = [[AVCaptureSession alloc]init];
    if ([self.session canSetSessionPreset:AVCaptureSessionPresetPhoto]) {
        self.session.sessionPreset = AVCaptureSessionPresetPhoto;
    }
    if ([self.session canAddInput:self.input]) {
        [self.session addInput:self.input];
    }
    
    if ([self.session canAddOutput:self.imageOutPut]) {
        [self.session addOutput:self.imageOutPut];
    }
    
    [self.view.layer addSublayer:self.previewLayer];
    
    //开始启动
    [self.session startRunning];
    if ([self.device lockForConfiguration:nil]) {
        if ([self.device isFlashModeSupported:AVCaptureFlashModeAuto]) {
            [self.device setFlashMode:AVCaptureFlashModeAuto];
        }
        //自动白平衡
        if ([self.device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
            [self.device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
        }
        
        [self.device unlockForConfiguration];
    }
    
}


- (void)reSetCaptureRect {
    CGPoint contentCenter =CGPointMake([UIScreen mainScreen].bounds.size.width/2.0, ([UIScreen mainScreen].bounds.size.height -80 -64)/2.0 +64);
    if (@available(iOS 13.0, *)) {
        contentCenter =CGPointMake([UIScreen mainScreen].bounds.size.width/2.0, ([UIScreen mainScreen].bounds.size.height -80 -44 -self.view.safeAreaInsets.top -self.view.safeAreaInsets.bottom)/2.0 +44 +self.view.safeAreaInsets.top);
    }
    if (self.direction == CameraDirectionHorizontal) {
        // 抓取区域
        CGFloat width =[UIScreen mainScreen].bounds.size.width*2.0/3;
        self.captureRect =CGRectMake(contentCenter.x -width/2.0, contentCenter.y -1.58 *width/2, width, 1.58 *width);
        // 提示语言
        self.tipLabel.bounds =CGRectMake(0, 0, self.captureRect.size.height, 40);
        self.tipLabel.center =CGPointMake(CGRectGetMaxX(self.captureRect) +20 +6, CGRectGetMidY(self.captureRect));
        _tipLabel.transform = CGAffineTransformMakeRotation(M_PI/2);
    } else {
        // 抓取区域
        CGFloat width =[UIScreen mainScreen].bounds.size.width*3.0/4;
        self.captureRect =CGRectMake(contentCenter.x -width/2.0, contentCenter.y -1.41 *width/2, width, 1.41 *width);
        // 提示语言
        self.tipLabel.bounds =CGRectMake(0, 0, self.captureRect.size.width, 40);
        self.tipLabel.center =CGPointMake(CGRectGetMidX(self.captureRect), CGRectGetMinY(self.captureRect) -20 -10);
    }
    self.captureView.captureRect =self.captureRect;
}

#pragma mark - 聚焦
- (void)focusGesture:(UITapGestureRecognizer*)gesture{
    CGPoint point = [gesture locationInView:gesture.view];
    [self focusAtPoint:point];
}
- (void)focusAtPoint:(CGPoint)point{
    CGSize size = self.view.bounds.size;
    CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );
    NSError *error;
    if ([self.device lockForConfiguration:&error]) {
        
        if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
            [self.device setFocusPointOfInterest:focusPoint];
            [self.device setFocusMode:AVCaptureFocusModeAutoFocus];
        }
        
        if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose ]) {
            [self.device setExposurePointOfInterest:focusPoint];
            [self.device setExposureMode:AVCaptureExposureModeAutoExpose];
        }
        
        [self.device unlockForConfiguration];
        self.focusView.center = point;
        _focusView.hidden = NO;
        self.focusView.alpha = 1;
        [UIView animateWithDuration:0.2 animations:^{
            self.focusView.transform = CGAffineTransformMakeScale(1.25f, 1.25f);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.3 animations:^{
                self.focusView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
            } completion:^(BOOL finished) {
                [self hiddenFocusAnimation];
            }];
        }];
    }
    
}
#pragma mark - 拍照
- (void)shutterCamera
{
    if (self.photoBtn.selected) {
        return;
    }
    AVCaptureConnection * videoConnection = [self.imageOutPut connectionWithMediaType:AVMediaTypeVideo];
    if (!videoConnection) {
        NSLog(@"take photo failed!");
        return;
    }
    
    [self.imageOutPut captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        if (imageDataSampleBuffer == NULL) {
            return;
        }
        NSData * imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        self.image = [UIImage imageWithData:imageData];
    
        self.imageDict = @{@"image":self.image,@"info":@{@"PHImageFileUTIKey":@".jpeg"}};
        [self.session stopRunning];
        self.imageView.image =self.image;
        [self.view insertSubview:self.imageView belowSubview:self.captureView];
        NSLog(@"image size = %@",NSStringFromCGSize(self.image.size));
        self.photoBtn.selected = YES;
        self.reCamBtn.hidden = NO;
        self.confirmBtn.hidden = NO;
    }];
}


#pragma mark - 取消 返回上级
-(void)cancle{
    [self.imageView removeFromSuperview];
    [self.session stopRunning];
    [self dismissViewControllerAnimated:YES completion:nil];

}
#pragma mark - 重新拍照
- (void)reCam{
    self.imageView.image = nil;
    [self.imageView removeFromSuperview];
    [self.session startRunning];
    self.photoBtn.selected = NO;
    self.reCamBtn.hidden = YES;
    self.confirmBtn.hidden = YES;
}


#pragma mark - 选择照片 返回上级
- (void)selectImage{
    UIImage *image1 = [self.image clipImage:[UIScreen mainScreen].bounds.size];
    CGImageRef cgRef = image1.CGImage;
    CGFloat widthScale = image1.size.width / [UIScreen mainScreen].bounds.size.width;
    CGFloat heightScale = image1.size.height / [UIScreen mainScreen].bounds.size.height;
    
    CGRect r = CGRectMake(self.captureRect.origin.x *widthScale, (self.captureRect.origin.y) *heightScale, self.captureRect.size.width *widthScale, self.captureRect.size.height *heightScale);
    
    CGImageRef imageRef = CGImageCreateWithImageInRect(cgRef, r);
    
    UIImage *thumbScale = [UIImage imageWithCGImage:imageRef];
    image1 = thumbScale;

    
    if (self.direction == CameraDirectionHorizontal) {
        image1 =[UIImage imageWithCGImage:image1.CGImage scale:image1.scale orientation:UIImageOrientationRight];
        CGAffineTransform transform = CGAffineTransformIdentity;
        transform = CGAffineTransformTranslate(transform, image1.size.width, 0);
        transform = CGAffineTransformRotate(transform, M_PI_2);
        CGContextRef ctx = CGBitmapContextCreate(NULL, image1.size.width, image1.size.height, CGImageGetBitsPerComponent(image1.CGImage), 0,CGImageGetColorSpace(image1.CGImage),CGImageGetBitmapInfo(image1.CGImage));
        CGContextConcatCTM(ctx, transform);
        CGContextDrawImage(ctx, CGRectMake(0,0,image1.size.height,image1.size.width), image1.CGImage);
        CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
        UIImage *img = [UIImage imageWithCGImage:cgimg];
        CGContextRelease(ctx);
        CGImageRelease(cgimg);
        image1 =img;
    }
    
    self.image = image1;
    //返回的时候把图片传回去
    self.imageblock(self.image);
    
    [self dismissViewControllerAnimated:YES completion:nil];
    
}


- (void)focusDidFinsh{
    self.focusView.hidden = YES;
    self.focusView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
}

- (void)startFocusAnimation{
    self.focusView.hidden = NO;
    self.focusView.transform = CGAffineTransformMakeScale(1.25f, 1.25f);//将要显示的view按照正常比例显示出来
    [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
  
    [UIView setAnimationDidStopSelector:@selector(hiddenFocusAnimation)];
    [UIView setAnimationDuration:0.5f];//动画时间
    self.focusView.transform = CGAffineTransformIdentity;//先让要显示的view最小直至消失
    [UIView commitAnimations]; //启动动画
    //相反如果想要从小到大的显示效果，则将比例调换
    
}
- (void)hiddenFocusAnimation{
    [UIView beginAnimations:nil context:UIGraphicsGetCurrentContext()];
    [UIView setAnimationDelay:3];
    self.focusView.alpha = 0;
    [UIView setAnimationDuration:0.5f];//动画时间
    [UIView commitAnimations];
    
}



#pragma mark - 检查相机权限
- (BOOL)canUserCamear{
    AVAuthorizationStatus authStatus =[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusDenied) {
        return NO;
    }
    else{
        return YES;
    }
    return YES;
}


#pragma mark - 使用AVMediaTypeVideo 指明self.device代表视频，默认使用后置摄像头进行初始化
-(AVCaptureDevice *)device{
    if (_device == nil) {
        
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    }
    return _device;
}
#pragma mark - 取消
-(UIButton *)cancleBtn {
    if (_cancleBtn == nil) {
        _cancleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _cancleBtn.frame = CGRectMake(40, [UIApplication sharedApplication].statusBarFrame.size.height +15, 30, 30);
        [_cancleBtn setImage:[UIImage imageNamed:@"cancelPhoto"] forState:(UIControlStateNormal)];
        [_cancleBtn addTarget:self action:@selector(cancle) forControlEvents:UIControlEventTouchUpInside];
    }
    return  _cancleBtn ;
}

#pragma mark - 下方功能区

-(UIView *)bottomView{
    if (!_bottomView) {
        _bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-80, self.view.frame.size.width, 80)];
        _bottomView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
        _bottomView.autoresizingMask =UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
//        [_bottomView addSubview:self.btn]
        [_bottomView addSubview:self.reCamBtn];
        [_bottomView addSubview:self.photoBtn];
        [_bottomView addSubview:self.confirmBtn];
    }
    return _bottomView;
}
-(UIButton *)reCamBtn{
    if (_reCamBtn == nil) {
        _reCamBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _reCamBtn.frame = CGRectMake(40, 25, 80, 30);
        _reCamBtn.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
        [_reCamBtn addTarget:self action:@selector(reCam) forControlEvents:UIControlEventTouchUpInside];
        [_reCamBtn setTitle:@"重新拍照" forState:UIControlStateNormal];
        [_reCamBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _reCamBtn.hidden = YES;
    }
    return _reCamBtn;
}
-(UIButton *)photoBtn{
    if (_photoBtn == nil) {
        _photoBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _photoBtn.frame = CGRectMake(self.bottomView.frame.size.width/2.0 -30, self.bottomView.frame.size.height/2.0 -30, 60, 60);
        _photoBtn.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
        [_photoBtn setImage:[UIImage imageNamed:@"photograph"] forState: UIControlStateNormal];
        [_photoBtn setImage:[UIImage imageNamed:@"photograph_Select"] forState:UIControlStateSelected];
        [_photoBtn addTarget:self action:@selector(shutterCamera) forControlEvents:UIControlEventTouchUpInside];
    }
    return _photoBtn;
}
-(UIButton *)confirmBtn {
    if (_confirmBtn == nil) {
        _confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _confirmBtn.frame = CGRectMake(self.bottomView.frame.size.width-120, 25, 80, 30);
        _confirmBtn.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
        [_confirmBtn addTarget:self action:@selector(selectImage) forControlEvents:UIControlEventTouchUpInside];
        [_confirmBtn setTitle:@"选择照片" forState:UIControlStateNormal];
        [_confirmBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _confirmBtn.hidden = YES;
    }
    return _confirmBtn;
}
#pragma mark - 加载照片的视图
-(UIImageView *)imageView{
    if (_imageView == nil) {
        _imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
        _imageView.autoresizingMask =UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        //这里要注意，图片填充方式的选择让图片不要变形了
        [_imageView setContentMode:UIViewContentModeScaleAspectFill];
        _imageView.clipsToBounds = YES;
        _imageView.image = _image;
    }
    return _imageView;
}
#pragma mark - 对焦区域
-(UIImageView *)focusView{
    if (_focusView == nil) {
        _focusView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 80, 80)];
        _focusView.backgroundColor = [UIColor clearColor];
        _focusView.image = [UIImage imageNamed:@"foucs80pt"];
        _focusView.hidden = YES;
    }
    return _focusView;
}

- (SW_CaptureView *)captureView {
    if (_captureView == nil) {
        _captureView = [[SW_CaptureView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        _captureView.autoresizingMask =UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    }
    return _captureView;
}

- (UILabel *)tipLabel {
    if (_tipLabel == nil) {
        _tipLabel = [[UILabel alloc] init];
        _tipLabel.center = self.view.center;
        _tipLabel.text = @"拍摄时，请将实物对准绿色边框线，并将证件放正";
        _tipLabel.textColor = [UIColor whiteColor];
        _tipLabel.numberOfLines = 1;
        _tipLabel.adjustsFontSizeToFitWidth =YES;
        _tipLabel.textAlignment = NSTextAlignmentCenter;
        _tipLabel.font = [UIFont systemFontOfSize:20];
    }
    
    return _tipLabel;
}

#pragma mark - 使用self.session，初始化预览层，self.session负责驱动input进行信息的采集，layer负责把图像渲染显示
- (AVCaptureVideoPreviewLayer *)previewLayer{
    if (_previewLayer == nil) {
        _previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
        _previewLayer.frame = [UIScreen mainScreen].bounds;
        _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    }
    return  _previewLayer;
}
-(AVCaptureStillImageOutput *)imageOutPut{
    if (_imageOutPut == nil) {
        _imageOutPut = [[AVCaptureStillImageOutput alloc] init];
    }
    return _imageOutPut;
}
#pragma mark - 初始化输入
-(AVCaptureDeviceInput *)input{
    if (_input == nil) {
        
        _input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
    }
    return _input;
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
